package com.tcj.myprogram.voiceschedule.db;

import java.io.File;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabaseCorruptException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.tcj.myprogram.memorialday.BaseActivity;

/**
 * This application provider(SQLITE).
 * 
 * @author tsengchienjung
 * 
 */
public class DBProvider extends ContentProvider {
	private static final String TAG = BaseActivity.TAG_BASE + "DBProvider";
	/**
	 * DB file name
	 */
	private static final String DATABASE_NAME = "memory_day.db";
	
	/**
	 * DB verstion
	 */
	private static final int DATABASE_VERSION = 2;
	
	/**
	 * Provider authority
	 */
	static final String AUTHORITY = "tseng_chien_jung_memeory_day";

	private SQLiteOpenHelper mOpenHelper;

	@Override
	public boolean onCreate() {
		try {
			mOpenHelper = new DBHelper(getContext());
		} catch (SQLiteDatabaseCorruptException sdce) {
			File db = getContext().getDatabasePath(DATABASE_NAME);
			Log.e(TAG,
					"open MeetingDraw database error, system will delete database to re-create databse");
			if (db.exists() && db.delete()) {
				mOpenHelper = new DBHelper(getContext());
			}
		}

		return true;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SqlArguments args = new SqlArguments(uri, selection, selectionArgs);

		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		int count = db.delete(args.table, args.where, args.args);

		return count;
	}

	@Override
	public String getType(Uri uri) {
		SqlArguments args = new SqlArguments(uri, null, null);
		if (TextUtils.isEmpty(args.where)) {
			return "vnd.android.cursor.dir/" + args.table;
		} else {
			return "vnd.android.cursor.item/" + args.table;
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SqlArguments args = new SqlArguments(uri);

		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		try {
			final long rowId = db.insert(args.table, null, values);

			if (rowId <= 0)
				return null;

			uri = ContentUris.withAppendedId(uri, rowId);

		} catch (SQLiteConstraintException sce) {
			Log.d(BaseActivity.TAG, "insert constraint  with uri=" + uri);
		}

		return uri;
	}

	@Override
	public int bulkInsert(Uri uri, ContentValues[] values) {
		SqlArguments args = new SqlArguments(uri);
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		db.beginTransaction();
		try {
			int numValues = values.length;
			for (int i = 0; i < numValues; i++) {
				if (db.insert(args.table, null, values[i]) < 0)
					return 0;
			}
			db.setTransactionSuccessful();
		} finally {
			db.endTransaction();
		}

		return values.length;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SqlArguments args = new SqlArguments(uri, selection, selectionArgs);
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		qb.setTables(args.table);

		SQLiteDatabase db = mOpenHelper.getReadableDatabase();
		Cursor result = qb.query(db, projection, args.where, args.args, null,
				null, sortOrder);
		result.setNotificationUri(getContext().getContentResolver(), uri);

		return result;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SqlArguments args = new SqlArguments(uri, selection, selectionArgs);

		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		int count = db.update(args.table, values, args.where, args.args);

		return count;
	}

	private static class DBHelper extends SQLiteOpenHelper {
		Context context;

		public DBHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
			this.context = context;
		}

		@Override
		/**
		 * 初始Table
		 */
		public void onCreate(SQLiteDatabase db) {
			
		}

		@Override
		/**
		 * 不同的DB version會觸發這個Method
		 */
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			StringBuilder sb = null;
			switch (newVersion) {
			
			}
		}
	}

	/**
	 * 
	 * SQL argument
	 * 
	 */
	static class SqlArguments {
		public final String table;
		public final String where;
		public final String[] args;

		SqlArguments(Uri url, String where, String[] args) {
			if (url.getPathSegments().size() == 1) {
				this.table = url.getPathSegments().get(0);
				this.where = where;
				this.args = args;
			} else if (url.getPathSegments().size() != 2) {
				throw new IllegalArgumentException("Invalid URI: " + url);
			} else if (!TextUtils.isEmpty(where)) {
				throw new UnsupportedOperationException(
						"WHERE clause not supported: " + url);
			} else {
				this.table = url.getPathSegments().get(0);
				this.where = "_id=" + ContentUris.parseId(url);
				this.args = null;
			}
		}

		SqlArguments(Uri url) {
			if (url.getPathSegments().size() == 1) {
				table = url.getPathSegments().get(0);
				where = null;
				args = null;
			} else {
				throw new IllegalArgumentException("Invalid URI: " + url);
			}
		}
	}

}